#include <bolt.h>
#include "pkt_queue.h"
#include "prot_icmp.h"

int debug_icmp = 0;

static bool reset_scpstp(struct llbuf *ll)
{
  /** cause_reset() */
  return false;
}

static bool icmp_rx_unreachable(struct llbuf *ll)
{
  struct iphdr *in_iph = (struct iphdr *)(ll->l4_ptr + 8);
  if (in_iph->protocol != IPPROTO_TCP)
    return pkt_event_send(ll->out, ll);
  return reset_scpstp(ll);
}

bool icmp_rx(struct llbuf *ll)
{
  struct icmphdr *icmp = (struct icmphdr *)ll->l4_ptr;
  switch (icmp->type) {
  case ICMP_ECHOREPLY:
  case ICMP_SOURCE_QUENCH:
  case ICMP_REDIRECT:
  case ICMP_ECHO:
  case ICMP_ROUTERADVERT:
  case ICMP_ROUTERSOLICIT:
  case ICMP_TIME_EXCEEDED:
  case ICMP_PARAMETERPROB:
  case ICMP_TIMESTAMP:
  case ICMP_TIMESTAMPREPLY:
  case ICMP_INFO_REQUEST:
  case ICMP_INFO_REPLY:
  case ICMP_ADDRESS:
  case ICMP_ADDRESSREPLY:
    return pkt_event_send(ll->out, ll);
  case ICMP_DEST_UNREACH:
    return icmp_rx_unreachable(ll);
  default:
    ICMP_LOG("ICMP unknown option\n");
    break;
  }
  return false;
}

bool icmp_tx(struct llbuf *ll)
{
  return false;
}

BOLT(debug_icmp, "debug icmp on")
{
  debug_icmp = 1;
}

BOLT(undebug_icmp, "debug icmp off")
{
  debug_icmp = 0;
}

BOLT_PROFILE(icmp, "", icmp_profile, desc)
{
  if (debug_icmp)
    cmd_load_profile(desc, "debug icmp on");
  cmd_load_profile(desc, "\n");
}



